﻿using CSRedis;
using System;
using System.Collections.Generic;
using System.Text;
using static CSRedis.CSRedisClient;

namespace CommandLib
{
    /// <summary>
    /// Redis缓存帮助类
    /// </summary>
    public sealed class CSRedisHelper
    {
        private static CSRedisClient redisClient;
        /// <summary>
        /// 缓存注册
        /// </summary>
        /// <param name="ConnectionString"></param>
        public static void Init(string ConnectionString)
        {
            redisClient = new CSRedisClient(ConnectionString);
        }
        /// <summary>
        /// 哨兵模式集群化
        /// </summary>
        /// <param name="constr">连接参数如：master,password=123456,poolsize=50,connectTimeout=200,ssl=false</param>
        /// <param name="sentinels"> 哨兵节点，如：127.0.0.1:26379，127.0.0.2:26379</param>
        public static void Init(string constr, string[] sentinels, bool readOnly = false)
        {
            redisClient = new CSRedisClient(constr, sentinels, readOnly);
        }

        /// <summary>
        /// 获取缓存
        /// </summary>
        /// <typeparam name="T">类型</typeparam>
        /// <param name="key">缓存键</param>
        /// <returns></returns>
        public static T Get<T>(string key)
        {
            return redisClient.Get<T>(key);
        }
        /// <summary>
        /// 设置缓存
        /// </summary>
        /// <param name="key">主键</param>
        /// <param name="Value">值</param>
        /// <param name="times">过期时间：默认不过期 单位是秒</param>
        public static void Set(string key, object Value, int times = -1)
        {
            redisClient.Set(key, Value, times);
        }
        /// <summary>
        /// 设置缓存
        /// </summary>
        /// <param name="key">主键</param>
        /// <param name="Value">值</param>
        /// <param name="times">过期时间</param>
        public static void Set(string key, object Value, TimeSpan times)
        {
            redisClient.Set(key, Value, times);
        }
        /// <summary>
        /// 删除缓存
        /// </summary>
        /// <param name="key"></param>
        public static void Clear(string key)
        {

            redisClient.Del(key);
        }
        /// <summary>
        /// 广播/消息发部
        /// </summary>
        /// <param name="channelName">发部通道名</param>
        /// <param name="comtext">发部内容</param>
        /// <returns></returns>
        public static bool Publish(string channelName, string comtext)
        {
            return redisClient.Publish(channelName, comtext) > 0;

        }

        /// <summary>
        /// 广播/消息订阅
        /// </summary>
        /// <param name="channels">委托函数 如：("chan1", msg => Console.WriteLine(msg.Body))</param>    
        public static void Subscribe(params (string, Action<SubscribeMessageEventArgs>)[] channels)
        {
            redisClient.Subscribe(channels);
        }

        /// <summary>
        ///  推送/生产者（挣抢模式）
        /// </summary>
        /// <param name="channelName">发部通道名</param>
        /// <param name="comtext">发部内容</param>
        /// <returns></returns>
        public static bool LPublish(string channelName, string comtext)
        {
            return redisClient.LPush(channelName, comtext) > 0;
        }

        /// <summary>
        /// 订阅消息，非堵塞订阅(消费者/挣抢模式)。
        /// </summary>
        /// <param name="listKey">通道</param>
        /// <param name="clientId">客户端ID</param>
        /// <param name="onMessage">信息</param>
        public static void SubscribeListBroadcast(string listKey, string clientId, Action<string> onMessage)
        {

            redisClient.SubscribeListBroadcast(listKey, clientId, onMessage);
        }

        /// <summary>
        /// 挣抢模式，只能有一个订阅能拿到消息(消费者)
        /// </summary>
        /// <param name="listKey">通道</param>
        /// <param name="onMessage">信息委托函数</param>
        public static void SubscribeList(string listKey, Action<string> onMessage)
        {
            redisClient.SubscribeList(listKey, onMessage);

        }
        /// <summary>
        /// 消费者模式
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="ChanngKey"></param>
        public static T BLPOP<T>(String ChanngKey)
        {
            //一个小时检查一次超时
            return redisClient.BLPop<T>(60 * 60, ChanngKey);
        }

    }
}
